package com.tek.ding.faceding.ui.login;

import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.Looper;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AlertDialog;

import com.jakewharton.rxbinding4.view.RxView;
import com.jakewharton.rxbinding4.widget.RxTextView;
import com.lxj.xpopup.util.KeyboardUtils;
import com.tbruyelle.rxpermissions3.RxPermissions;
import com.tek.ding.faceding.R;
import com.tek.ding.faceding.base.BaseActivity;
import com.tek.ding.faceding.bean.AppVersion;
import com.tek.ding.faceding.bean.BaseBean;
import com.tek.ding.faceding.bean.Staff;
import com.tek.ding.faceding.bean.Store;
import com.tek.ding.faceding.presenter.login.LoginContract;
import com.tek.ding.faceding.presenter.login.LoginModel;
import com.tek.ding.faceding.presenter.login.LoginPresenter;
import com.tek.ding.faceding.ui.MainActivity;
import com.tek.ding.faceding.utils.BaseTools;
import com.tek.ding.faceding.utils.CheckNetwork;
import com.tek.ding.faceding.utils.Constants;
import com.tek.ding.faceding.utils.DialogUtils;
import com.tek.ding.faceding.utils.MyToastUtils;
import com.tek.ding.faceding.utils.SPUtils;
import com.tek.ding.faceding.utils.SoftHideKeyBoardUtil;
import com.tek.ding.faceding.widget.StoreDialog;
import com.tencent.map.geolocation.TencentLocation;
import com.tencent.map.geolocation.TencentLocationListener;
import com.tencent.map.geolocation.TencentLocationManager;
import com.tencent.map.geolocation.TencentLocationRequest;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.lang.ref.WeakReference;
import java.util.List;
import java.util.concurrent.TimeUnit;

import io.reactivex.rxjava3.core.Observable;

public class LoginActivity extends BaseActivity<LoginPresenter> implements LoginContract.LoginView {

    private final static String TAG = LoginActivity.class.getName();

    private AppVersion appVersion;
    private EditText et_phone, et_password;
    private Button bt_ok;

    private String deviceId = "";
    private Integer versionCode = 0;
    private String storeUid, address, lng, lat;

    // 腾讯定位
    private TencentLocationManager mLocationManager;
    private InnerLocationListener mLocationListener;

    private RxPermissions rxPermission = new RxPermissions(this);
    private String[] permissions = {
            android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
            android.Manifest.permission.READ_EXTERNAL_STORAGE,
            android.Manifest.permission.CAMERA,
            android.Manifest.permission.ACCESS_NETWORK_STATE,
            android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
            android.Manifest.permission.ACCESS_FINE_LOCATION,
            android.Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS,
//            android.Manifest.permission.POST_NOTIFICATIONS
    };

    public static void startActivity(Context context) {
        context.startActivity(new Intent(context, LoginActivity.class));
    }

    public static void startActivity(Context context, AppVersion appVersion) {
        context.startActivity(new Intent(context, LoginActivity.class)
                .putExtra(INTENT_DATA, appVersion));
    }

    @Override
    protected int getLayoutId() {
        return R.layout.activity_login;
    }

    @Override
    protected String setTitleName() {
        return "登录";
    }

    @Override
    protected LoginPresenter createPresenter() {
        return new LoginPresenter(new LoginModel(), this);
    }

    @Override
    protected void init() {
        setTitleBackGone();

        // 解决键盘档住输入框
        SoftHideKeyBoardUtil.assistActivity(this);

        tbBack.setVisibility(View.INVISIBLE);
        et_phone = find(R.id.et_phone);
        et_password = find(R.id.et_password);
        bt_ok = find(R.id.bt_ok);

        // 获取设备标识
        String pseudoID = BaseTools.getPseudoID();
        // 获取androidId
        String androidId = BaseTools.getAndroidId(this);
        deviceId = pseudoID + "_" + androidId;
        // 获取版本号
        versionCode = BaseTools.getVersionCode(this);
        SPUtils.putString(Constants.DEVICE_ID, deviceId);
        SPUtils.putInt(Constants.VERSION_CODE, versionCode);
        storeUid = SPUtils.getString(Constants.STORE_UID, "");

        String phoneValue = SPUtils.getString(Constants.PHONE, "");
        String passwordValue = SPUtils.getString(Constants.PASSWORD, "");
        if (!TextUtils.isEmpty(phoneValue) && !TextUtils.isEmpty(passwordValue)) {
            et_phone.setText(phoneValue);
            et_password.setText(passwordValue);
        }

        RxView.clicks(tbTitle)
                .throttleFirst(2, TimeUnit.SECONDS)
                .subscribe(unit -> {
                    MyToastUtils.show("设备号：" + deviceId + "\n版本号：" + versionCode);
                });

        Observable<CharSequence> obPhone = RxTextView.textChanges(et_phone);
        Observable<CharSequence> obPass = RxTextView.textChanges(et_password);
        Observable.combineLatest(obPhone, obPass, (phone, pass) -> isPhone(phone.toString()) && isPass(pass.toString()))
                .subscribe(aBoolean -> {
                    bt_ok.setEnabled(aBoolean);
                }).isDisposed();

        RxView.clicks(bt_ok)
                .throttleFirst(2, TimeUnit.SECONDS)
                .compose(rxPermission.ensureEachCombined(permissions))
                .subscribe(permission -> {
                    if (permission.granted) {
                        if (StringUtils.isBlank(deviceId))
                            MyToastUtils.show("设备标识获取失败");
                        else if (null == versionCode)
                            MyToastUtils.show("版本号获取失败");
                        if (!checkManageOverlayPermission())
                            // 安卓13检查悬浮窗权限
                            setManageOverlayPermission();
                        else if (!checkManageAllFileAccessPermission()) {
                            // 安卓13检查存储权限
                            setManageAllFileAccessPermission();
                        } else if (!checkInstallPermission()) {
                            // 检查安装未知应用安装包的权限
                            setInstallPermission();
                        } else {
                            String username = et_phone.getText().toString();
                            String password = et_password.getText().toString();
                            SPUtils.putString(Constants.PHONE, username);
                            SPUtils.putString(Constants.PASSWORD, password);

                            if (!CheckNetwork.isNetworkConnected(this)) {
                                MyToastUtils.showLong(getResources().getText(R.string.error_network));
                            } else {
                                // 获取账号的门店集合
                                presenter.getStoreList(storeUid, username);
                            }
                        }
                    } else if (permission.shouldShowRequestPermissionRationale) {
                        // 用户拒绝了该权限，没有选中『不再询问』（Never ask again）,那么下次再次启动时。还会提示请求权限的对话框
                        Log.e(TAG, permission.name + " is denied. More info should be provided.");
                    } else {
                        // 用户拒绝了该权限，而且选中『不再询问』
                        MyToastUtils.show("用户拒绝权限，而且选中『不再询问』");
                    }
                }).isDisposed();

        // 关闭键盘
        et_password.setOnEditorActionListener((v, actionId, event) -> {
            KeyboardUtils.hideSoftInput(v);
            return false;
        });

        // 申请权限
        requestPermissions();

        AppVersion appVersion = getIntent().getParcelableExtra(INTENT_DATA);
        if (null != appVersion) {
            DialogUtils.showUpdateDialog(this, appVersion);
        }
    }

    /**
     * 检查悬浮窗权限
     */
    private boolean checkManageOverlayPermission() {
        boolean c = true;
        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            c = Settings.canDrawOverlays(this);
        }
        return c;
    }

    /**
     * 开启悬浮窗权限
     */
    private void setManageOverlayPermission() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("需要开启悬浮窗权限，请去开启权限！");
        builder.setMessage("");
        builder.setPositiveButton("确定", (dialogInterface, i) -> {
            Intent intent = new Intent();
            intent.addCategory("android.intent.category.DEFAULT");
            intent.setAction(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
            intent.setData(Uri.parse(String.format("package:%s", getApplicationContext().getPackageName())));
            startActivityForResult(intent, 10087);
        });
        builder.setNegativeButton("取消", null);
        builder.setCancelable(false);
        AlertDialog dialog = builder.create();
        dialog.show();
    }

    /**
     * 安卓13检查存储权限的方法
     *
     * @return
     */
    private boolean checkManageAllFileAccessPermission() {
        // 先检查是否有安装app权限
        //先获取是否有安装未知来源应用的权限
        boolean c = true;
        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            c = Environment.isExternalStorageManager();
        }
        return c;
    }

    /**
     * 安卓13开启存储权限的方法
     */
    private void setManageAllFileAccessPermission() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("需要开启存储权限，请去开启权限！");
        builder.setMessage("");
        builder.setPositiveButton("确定", (dialogInterface, i) -> {
            Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
            intent.addCategory("android.intent.category.DEFAULT");
            intent.setData(Uri.parse(String.format("package:%s", getApplicationContext().getPackageName())));
            startActivityForResult(intent, 10088);
        });
        builder.setNegativeButton("取消", null);
        builder.setCancelable(false);
        AlertDialog dialog = builder.create();
        dialog.show();
    }

    /**
     * 发现新版本后检查安装权限并去下载
     */
    private boolean checkInstallPermission() {
        // 先检查是否有安装app权限
        //先获取是否有安装未知来源应用的权限
        boolean c = true;
        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            c = getPackageManager().canRequestPackageInstalls();
        }
        return c;
    }

    /**
     * 开启安装权限
     */
    private void setInstallPermission() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("更新版本需要开启安装权限，请去开启权限！");
        builder.setMessage("");
        builder.setPositiveButton("确定", (dialogInterface, i) -> {
            Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES);
            intent.addCategory("android.intent.category.DEFAULT");
            intent.setData(Uri.parse(String.format("package:%s", getApplicationContext().getPackageName())));
            startActivityForResult(intent, 10086);
        });
        builder.setNegativeButton("取消", null);
        builder.setCancelable(false);
        AlertDialog dialog = builder.create();
        dialog.show();
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    private void startInstallPermissionSettingActivity() {
        Uri packageURI = Uri.parse("package:" + getPackageName());
        //注意这个是8.0新API
        Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, packageURI);
        startActivityForResult(intent, 10086);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 10086 && resultCode == RESULT_OK) {
            if (!CheckNetwork.isNetworkConnected(this)) {
                MyToastUtils.showLong(getResources().getText(R.string.error_network));
            } else {
                // 检查版本并选择门店
                String username = et_phone.getText().toString();
                String password = et_password.getText().toString();
                if (StringUtils.isNotBlank(username) && StringUtils.isNotBlank(password))
                    presenter.checkVersionAndStores(storeUid, username, address, lng, lat);
            }
        } else {
            if (!checkManageOverlayPermission()) {
                // 安卓13检查悬浮窗权限
                setManageOverlayPermission();
            } else if (!checkManageAllFileAccessPermission()) {
                // 安卓13检查存储权限
                setManageAllFileAccessPermission();
            } else if (!checkInstallPermission()) {
                // 检查安装未知应用安装包的权限
                setInstallPermission();
            }
        }
    }

    /**
     * 申请权限
     */
    private void requestPermissions() {
        rxPermission.requestEach(permissions)
                .subscribe(permission -> {
                    String name = permission.name;
                    if (permission.granted) {
                        // 用户已经同意该权限
                        Log.d(TAG, permission.name + " is granted.");
                        // 定位权限已启用，则开启腾讯定位
                        if (permission.name.contains("ACCESS_FINE_LOCATION")) {
                            startLocation();
                        }
                    } else if (permission.shouldShowRequestPermissionRationale) {
                        // 用户拒绝了该权限，没有选中『不再询问』（Never ask again）,那么下次再次启动时。还会提示请求权限的对话框
                        Log.d(TAG, permission.name + " is denied. More info should be provided.");
                    } else {
                        // 用户拒绝了该权限，而且选中『不再询问』
                        Log.d(TAG, permission.name + " is denied.");
                    }
                });


        // 请求发布通知权限

//        if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.R) {
//            ActivityCompat.requestPermissions( this, Manifest.permission.POST_NOTIFICATIONS, 0);
//        }

        if (!checkManageOverlayPermission()) {
            setManageOverlayPermission();
        }
    }

    /**
     * 检查手机号
     */
    private boolean isPhone(String phone) {
        return phone.length() > 6;
    }

    /**
     * 检查密码
     */
    private boolean isPass(String pass) {
        return pass.length() >= 6;
    }


    @Override
    public void onCheckNewVersionOk(BaseBean<AppVersion> baseBean) {
        if (baseBean.success()) {
            if (baseBean.getData() != null) {
                // 发现有新版本需要升级
                appVersion = baseBean.getData();
                // 去下载
                DialogUtils.showUpdateDialog(this, appVersion);
                // 发现新版本停止定位
                stopLocation();
            }
        } else {
            MyToastUtils.show(baseBean.getMsg());
        }
    }

    @Override
    public void onLoginOk(BaseBean<Staff> baseBean) {
        if (baseBean.success()) {
            goMainActivity(baseBean.getData());
        } else {
            MyToastUtils.show(baseBean.getMsg());
        }
    }

    @Override
    public void onGetStaffStores(BaseBean<List<Store>> baseBean) {
        if (baseBean.success()) {
            List<Store> storeList = baseBean.getData();
            if (CollectionUtils.isEmpty(storeList)) {
                MyToastUtils.show("账号没有查到门店角色！");
            } else {
                if (storeList.size() == 1) {
                    // 只有一个门店，直接登录
                    String phone = et_phone.getText().toString();
                    String password = et_password.getText().toString();
                    // 检查新版本并登录
                    presenter.checkVersionAndLogin(storeList.get(0).getStoreUid(), phone, password, address, lng, lat);
                } else {
                    // 多个门店，先去选择
                    StoreDialog.Builder builder = new StoreDialog.Builder(this);
                    builder.setList(storeList)
                            .setCancelButton((dialog, which) -> {
                                Store store = builder.getData();
                                if (null != store) {
                                    String phone = et_phone.getText().toString();
                                    String password = et_password.getText().toString();
                                    // 检查新版本并登录
                                    presenter.checkVersionAndLogin(store.getStoreUid(), phone, password, address, lng, lat);
                                } else {
                                    MyToastUtils.show("门店信息获取异常！");
                                }
                                dialog.dismiss();
                            }).create().show();
                }
            }
        } else {
            MyToastUtils.show(baseBean.getMsg());
        }
    }

    /**
     * 登录成功去主页
     */
    private void goMainActivity(Staff data) {
        SPUtils.putString(Constants.STORE_UID, data.getStoreUid());
        SPUtils.putString(Constants.STAFF_UID, data.getUid());

        MainActivity.startActivity(this, data.getStoreName());
        finish();
    }

    /**
     * 定位初始化
     */
    private void startLocation() {
        /**
         * 设置用户是否同意隐私协议政策
         * 调用其他接口前必须首先调用此接口进行用户是否同意隐私政策的设置，传入true后才能正常使用定位功能
         */
        if (null == mLocationManager) {
            TencentLocationManager.setUserAgreePrivacy(true);

            Context applicationContext = getApplicationContext();
            mLocationManager = TencentLocationManager.getInstance(applicationContext);
            mLocationManager.setDeviceID(applicationContext, deviceId);
            mLocationListener = new InnerLocationListener(new WeakReference<>(this));

            int locMode = TencentLocationRequest.HIGH_ACCURACY_MODE;
            TencentLocationRequest request = TencentLocationRequest.create()
                    //设置请求级别
                    .setRequestLevel(TencentLocationRequest.REQUEST_LEVEL_ADMIN_AREA)
                    //是否允许使用GPS
                    .setAllowGPS(true)
                    //是否需要开启室内定位
                    .setIndoorLocationMode(true)
                    // 设置定位模式
                    .setLocMode(locMode)
                    // 设置GPS优先
                    .setGpsFirst(true)
                    // 用户可定义GPS超时时间，超过该时间仍然没有卫星定位结果将返回网络定位结果
                    .setGpsFirstTimeOut(5 * 1000);

            // 发起单次定位请求
            mLocationManager.requestSingleFreshLocation(request, mLocationListener, Looper.getMainLooper());
        }
    }

    /**
     * 退出页面前停止定位
     */
    public void stopLocation() {
        if (null != mLocationManager) {
            mLocationManager.removeUpdates(mLocationListener);
            mLocationManager.disableForegroundLocation(true);
        }
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            moveTaskToBack(false);
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        moveTaskToBack(false);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        // 退出页面前停止定位
        stopLocation();
    }

    /**
     * 定位结果监听
     */
    private class InnerLocationListener implements TencentLocationListener {

        private WeakReference<LoginActivity> mMainActivityWRF;

        public InnerLocationListener(WeakReference<LoginActivity> mainActivityWRF) {
            mMainActivityWRF = mainActivityWRF;
        }

        @Override
        public void onLocationChanged(TencentLocation tencentLocation, int status, String reason) {
            if (null != mMainActivityWRF) {
                if (status == TencentLocation.ERROR_OK) {
                    // 定位成功
                    if (null != tencentLocation) {
                        String locationAddress = tencentLocation.getAddress();
                        if (StringUtils.isNotBlank(locationAddress)) {
                            lat = tencentLocation.getLatitude() + "";
                            lng = tencentLocation.getLongitude() + "";
                            address = locationAddress;
                        }
                    }
                } else {
                    // 定位失败
                }
            }
        }

        @Override
        public void onStatusUpdate(String s, int i, String s1) {

        }
    }
}
